package com.sgzn.sgpay.util;

import com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility;
import com.fasterxml.jackson.annotation.JsonInclude.Include;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * json处理工具
 * 
 * @author xinyue.zheng
 */
public class JsonMapperUtil {

    private static final Logger LOG = LoggerFactory.getLogger(JsonMapperUtil.class);

	private static final ObjectMapper objectMapper = new ObjectMapper()
			.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
            .setVisibility(PropertyAccessor.FIELD, Visibility.ANY)
			.setSerializationInclusion(Include.NON_NULL);

	private JsonMapperUtil() {
	}

    /**
     * 取得ObjectMapper的对象
     * @return
     */
	public static final ObjectMapper getObjectMapper() {
		return objectMapper;
	}

    /**
     * 将json格式的对象转为字符串
     * @param jsonValue json对象，可以是map
     * @return
     */
    public static final String jsonToString(Object jsonValue) {
        try {
            return getObjectMapper().writeValueAsString(jsonValue);
        } catch (JsonProcessingException e) {
            LOG.error(e.getMessage(), e);
            return null;
        }
    }

    /**
     * 将json字符串转为实体类entity
     * @param jsonStr json字符串
     * @return
     */
    public static final <T> T stringToBean(String jsonStr, Class<T> clz) {
        try {
            return getObjectMapper().readValue(jsonStr, clz);
        } catch (Exception e) {
            LOG.error(e.getMessage(), e);
        }
        return null;
    }

    /**
     * 将json字符串转为复杂的集合类
     * @param jsonStr json字符串
     * @param parametrized 包装类的实例类型
     * @param parametersFor 包装类接口类型
     * @param parameterClasses 包装类里的实体类型
     * @return
     */
    public static final <T> T stringToComplicatedObject(String jsonStr, Class<?> parametrized, Class<?> parametersFor,
            Class<?> parameterClasses) {
        JavaType javaType = getObjectMapper().getTypeFactory().constructParametrizedType(parametrized, parametersFor,
                parameterClasses);
        try {
            return getObjectMapper().readValue(jsonStr, javaType);
        } catch (Exception e) {
            LOG.error(e.getMessage(), e);
        }
        return null;
    }

}
